package file

import (
	"fmt"
	"os"
	"path/filepath"
	"strings"
)

func Contains(s []FileStruct, e FileStruct) bool {
	if s == nil {
		return false
	}
	i := index(s, e)
	return i >= 0
}

// Index 自定义 index 方法
func index(s []FileStruct, e FileStruct) int {
	if s == nil {
		return -1
	}

	for idx, f := range s {
		if f.Equals(&e) {
			return idx
		}
	}
	return -1
}

type FileStruct struct {
	_                  [0]func()   // disallow ==
	AbsFilePath        string      `name:"文件绝对路径"`
	fileName           string      `name:"文件名"`
	filenameWithoutExt string      `name:"文件名,不含扩展名"`
	fileState          os.FileInfo `name:"文件信息"`
}

// Equals 自定义比较逻辑
func (f *FileStruct) Equals(other *FileStruct) bool {
	// 仅比较绝对路径即可
	if strings.Compare(f.AbsFilePath, other.AbsFilePath) == 0 {
		return true
	}
	return false
}

func (f *FileStruct) IsZero() bool {
	return f.AbsFilePath == ""
}

// GetFileName 获取文件名
func (f *FileStruct) GetFileName() string {
	if f == nil || len(strings.TrimSpace(f.AbsFilePath)) == 0 {
		panic(fmt.Errorf("[FileStruct-getFileName]无法获取路径"))
	}

	if len(f.fileName) == 0 {
		base := filepath.Base(f.AbsFilePath)
		f.fileName = base
	}

	return f.fileName
}

// GetFilenameWithoutExt 获取文件名，不含扩展名
func (f *FileStruct) GetFilenameWithoutExt() string {
	if len(f.filenameWithoutExt) == 0 {
		filename := f.GetFileName()
		// 获取扩展名
		ext := filepath.Ext(filename)
		// 去除扩展名
		filenameWithoutExt := filename[:len(filename)-len(ext)]

		if len(filenameWithoutExt) == 0 {
			// 去除扩展名后文件名为空，直接使用文件名
			filenameWithoutExt = filename
		}
		f.filenameWithoutExt = filenameWithoutExt
	}

	return f.filenameWithoutExt
}

// GetModTimeStr 获取文件修改时间
func (f *FileStruct) GetModTimeStr(pattern string) string {
	if f.fileState == nil {
		f.initState()
	}

	return f.fileState.ModTime().Format(pattern)
}

// GetSize 获取文件大小
func (f *FileStruct) GetSize() int64 {

	if f.fileState == nil {
		f.initState()
	}

	return f.fileState.Size()
}

// 初始化文件信息
func (f *FileStruct) initState() {

	stat, err := os.Stat(f.AbsFilePath)
	if err != nil {
		panic(fmt.Errorf("获取 %s 文件状态时报错,err:%v", f.AbsFilePath, err))
	}
	f.fileState = stat
}
